package service

import (
	"context"
	"fmt"
	logger "gitee.com/zaper/private-logger"
	"gitee.com/zaper/service-center/os_env"
	"github.com/go-kratos/kratos/contrib/registry/etcd/v2"
	"github.com/go-kratos/kratos/v2/registry"
	clientv3 "go.etcd.io/etcd/client/v3"
	"math/rand"
	"os"
)

type DiscoveryAgent struct {
	clientEtcd *clientv3.Client
}

func NewDiscoveryAgent(cliEtcd *clientv3.Client) *DiscoveryAgent {
	return &DiscoveryAgent{
		clientEtcd: cliEtcd,
	}
}

func (discoveryManager *DiscoveryAgent) ServiceDiscover(serviceName string) ([]InstanceInfo, error) {
	logger.Infof("Discovery start, request is %s", serviceName)
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	appNameSpace := fmt.Sprintf("/%s", os.Getenv(os_env.AppNameSpaceKey))
	ktsEtcd := etcd.New(discoveryManager.clientEtcd, etcd.Context(ctx), etcd.Namespace(appNameSpace))
	serviceInstances, err := ktsEtcd.GetService(ctx, serviceName)
	if err != nil {
		logger.Errorf("get service info fail, err is %s", err)
		return nil, err
	}
	return parseKtsServiceToInstance(serviceInstances), nil
}

func (discoveryManager *DiscoveryAgent) ServiceDiscoverOnce(serviceName string) (*InstanceInfo, error) {
	instances, err := discoveryManager.ServiceDiscover(serviceName)
	if err != nil {
		logger.Errorf("discovery service fail. err is %s", err)
		return nil, err
	}

	return &instances[rand.Intn(len(instances))], nil
}

func parseKtsServiceToInstance(ktsService []*registry.ServiceInstance) []InstanceInfo {
	var instances []InstanceInfo
	var instance InstanceInfo
	for _, i := range ktsService {
		instance.ID = i.ID
		instance.Name = i.Name
		instance.Metadata = i.Metadata
		instance.Endpoints = i.Endpoints
		instances = append(instances, instance)
	}
	return instances
}
